/*      */ package com.zimbra.cs.service;
/*      */ 
/*      */ import com.zimbra.client.ZFolder;
/*      */ import com.zimbra.client.ZMailbox;
/*      */ import com.zimbra.client.ZMailbox.Options;
/*      */ import com.zimbra.common.account.Key.AccountBy;
/*      */ import com.zimbra.common.auth.ZAuthToken;
/*      */ import com.zimbra.common.httpclient.HttpClientUtil;
/*      */ import com.zimbra.common.localconfig.KnownKey;
/*      */ import com.zimbra.common.localconfig.LC;
/*      */ import com.zimbra.common.mime.ContentDisposition;
/*      */ import com.zimbra.common.mime.ContentType;
/*      */ import com.zimbra.common.service.ServiceException;
/*      */ import com.zimbra.common.service.ServiceException.Argument;
/*      */ import com.zimbra.common.service.ServiceException.Argument.Type;
/*      */ import com.zimbra.common.service.ServiceException.InternalArgument;
/*      */ import com.zimbra.common.util.HttpUtil;
/*      */ import com.zimbra.common.util.L10nUtil;
/*      */ import com.zimbra.common.util.L10nUtil.MsgKey;
/*      */ import com.zimbra.common.util.Log;
/*      */ import com.zimbra.common.util.LogFactory;
/*      */ import com.zimbra.common.util.Pair;
/*      */ import com.zimbra.common.util.StringUtil;
/*      */ import com.zimbra.common.util.ZimbraHttpConnectionManager;
/*      */ import com.zimbra.common.util.ZimbraLog;
/*      */ import com.zimbra.cs.account.Account;
/*      */ import com.zimbra.cs.account.AccountServiceException;
/*      */ import com.zimbra.cs.account.AuthToken;
/*      */ import com.zimbra.cs.account.Provisioning;
/*      */ import com.zimbra.cs.account.Server;
/*      */ import com.zimbra.cs.account.ZimbraAuthTokenEncoded;
/*      */ import com.zimbra.cs.httpclient.URLUtil;
/*      */ import com.zimbra.cs.mailbox.Document;
/*      */ import com.zimbra.cs.mailbox.Folder;
/*      */ import com.zimbra.cs.mailbox.MailItem;
/*      */ import com.zimbra.cs.mailbox.MailItem.Type;
/*      */ import com.zimbra.cs.mailbox.MailServiceException;
/*      */ import com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException;
/*      */ import com.zimbra.cs.mailbox.Mailbox;
/*      */ import com.zimbra.cs.mailbox.MailboxManager;
/*      */ import com.zimbra.cs.mailbox.Mountpoint;
/*      */ import com.zimbra.cs.mailbox.OperationContext;
/*      */ import com.zimbra.cs.service.admin.AdminAccessControl;
/*      */ import com.zimbra.cs.service.formatter.Formatter;
/*      */ import com.zimbra.cs.service.formatter.FormatterFactory;
/*      */ import com.zimbra.cs.service.formatter.FormatterFactory.FormatType;
/*      */ import com.zimbra.cs.service.util.ItemId;
/*      */ import com.zimbra.cs.service.util.UserServletUtil;
/*      */ import com.zimbra.cs.servlet.ZimbraServlet;
/*      */ import com.zimbra.cs.servlet.util.CsrfUtil;
/*      */ import com.zimbra.cs.util.AccountUtil;
/*      */ import java.io.FilterInputStream;
/*      */ import java.io.IOException;
/*      */ import java.io.InputStream;
/*      */ import java.util.ArrayList;
/*      */ import java.util.Arrays;
/*      */ import java.util.HashMap;
/*      */ import java.util.HashSet;
/*      */ import java.util.List;
/*      */ import java.util.Map;
/*      */ import java.util.Map.Entry;
/*      */ import javax.servlet.ServletException;
/*      */ import javax.servlet.http.HttpServletRequest;
/*      */ import javax.servlet.http.HttpServletResponse;
/*      */ import org.apache.commons.httpclient.Cookie;
/*      */ import org.apache.commons.httpclient.Header;
/*      */ import org.apache.commons.httpclient.HttpClient;
/*      */ import org.apache.commons.httpclient.HttpException;
/*      */ import org.apache.commons.httpclient.HttpMethod;
/*      */ import org.apache.commons.httpclient.HttpState;
/*      */ import org.apache.commons.httpclient.URI;
/*      */ import org.apache.commons.httpclient.methods.GetMethod;
/*      */ import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
/*      */ import org.apache.commons.httpclient.methods.PutMethod;
/*      */ import org.apache.commons.httpclient.methods.RequestEntity;
/*      */ import org.apache.commons.httpclient.params.HttpClientParams;
/*      */ import org.apache.commons.httpclient.params.HttpMethodParams;
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ public class UserServlet
/*      */   extends ZimbraServlet
/*      */ {
/*      */   private static final long serialVersionUID = -5313094316561384586L;
/*      */   public static final String SERVLET_PATH = "/home";
/*      */   public static final String QP_AUTHTOKEN = "authToken";
/*      */   public static final String QP_FMT = "fmt";
/*      */   public static final String QP_NOHIERARCHY = "nohierarchy";
/*      */   public static final String QP_ZLV = "zlv";
/*      */   public static final String QP_ID = "id";
/*      */   public static final String QP_LIST = "list";
/*      */   public static final String QP_IMAP_ID = "imap_id";
/*      */   public static final String QP_PART = "part";
/*      */   public static final String QP_BODY = "body";
/*      */   public static final String BODY_TEXT = "text";
/*      */   public static final String BODY_HTML = "html";
/*      */   public static final String QP_QUERY = "query";
/*      */   public static final String QP_SORT = "sort";
/*      */   public static final String QP_VIEW = "view";
/*      */   public static final String QP_TYPES = "types";
/*      */   public static final String QP_START = "start";
/*      */   public static final String QP_END = "end";
/*      */   public static final String QP_FREEBUSY_CALENDAR = "fbcal";
/*      */   public static final String QP_IGNORE_ERROR = "ignore";
/*      */   public static final String QP_PRESERVE_ALARMS = "preserveAlarms";
/*      */   public static final String QP_OFFSET = "offset";
/*      */   public static final String QP_LIMIT = "limit";
/*      */   public static final String QP_AUTH = "auth";
/*      */   public static final String QP_DISP = "disp";
/*      */   public static final String QP_NAME = "name";
/*      */   public static final String QP_CSVFORMAT = "csvfmt";
/*      */   public static final String QP_CSVLOCALE = "csvlocale";
/*      */   public static final String QP_CSVSEPARATOR = "csvsep";
/*      */   public static final String QP_VERSION = "ver";
/*      */   public static final String QP_HISTORY = "history";
/*      */   public static final String QP_LANGUAGE = "language";
/*      */   public static final String QP_COUNTRY = "country";
/*      */   public static final String QP_VARIANT = "variant";
/*      */   public static final String UPLOAD_NAME = "uploadName";
/*      */   public static final String UPLOAD_TYPE = "uploadType";
/*      */   public static final String QP_FBFORMAT = "fbfmt";
/*      */   public static final String QP_MANIFEST = "manifest";
/*      */   public static final String QP_DUMPSTER = "dumpster";
/*      */   public static final String QP_META = "meta";
/*      */   public static final String QP_EXUID = "exuid";
/*      */   public static final String AUTH_COOKIE = "co";
/*      */   public static final String AUTH_BASIC = "ba";
/*      */   public static final String AUTH_QUERYPARAM = "qp";
/*      */   public static final String AUTH_NO_SET_COOKIE = "nsc";
/*      */   public static final String AUTH_SET_COOKIE = "sc";
/*      */   public static final String AUTH_DEFAULT = "co,nsc,qp";
/*      */   public static final String HTTP_URL = "http_url";
/*      */   public static final String HTTP_STATUS_CODE = "http_code";
/*      */   public static final String QP_MAX_WIDTH = "max_width";
/*      */   public static final String QP_MAX_HEIGHT = "max_height";
/*      */   protected static final String MSGPAGE_BLOCK = "errorpage.attachment.blocked";
/*  252 */   public static final Log log = LogFactory.getLog(UserServlet.class);
/*      */   
/*      */   public static String getRestUrl(Account acct) throws ServiceException
/*      */   {
/*  256 */     return getServiceUrl(acct, "/home");
/*      */   }
/*      */   
/*      */   public static String getRestUrl(MailItem item) throws ServiceException
/*      */   {
/*  261 */     Account acct = item.getMailbox().getAccount();
/*  262 */     return getRestUrl(acct) + HttpUtil.urlEscape(item.getPath());
/*      */   }
/*      */   
/*      */   public static Formatter getFormatter(FormatterFactory.FormatType type) {
/*  266 */     return (Formatter)FormatterFactory.mFormatters.get(type);
/*      */   }
/*      */   
/*      */   private void sendError(UserServletContext ctxt, HttpServletRequest req, HttpServletResponse resp, String message) throws IOException {
/*  270 */     if (resp.isCommitted()) {
/*  271 */       log.info("Response already committed. Skipping sending error code for response");
/*  272 */       return;
/*      */     }
/*  274 */     if ((ctxt != null) && (!ctxt.cookieAuthHappened) && (ctxt.basicAuthAllowed()) && (!ctxt.basicAuthHappened)) {
/*  275 */       resp.addHeader("WWW-Authenticate", getRealmHeader(req, null));
/*  276 */       resp.sendError(401, L10nUtil.getMessage(L10nUtil.MsgKey.errMustAuthenticate, req, new Object[0]));
/*  277 */     } else if ((ctxt != null) && (ctxt.cookieAuthHappened) && (!ctxt.isCsrfAuthSucceeded()) && ((req.getMethod().equalsIgnoreCase("POST")) || (req.getMethod().equalsIgnoreCase("PUT"))))
/*      */     {
/*  279 */       resp.sendError(401, L10nUtil.getMessage(L10nUtil.MsgKey.errMustAuthenticate, req, new Object[0]));
/*      */     } else {
/*  281 */       resp.sendError(404, message);
/*      */     }
/*      */   }
/*      */   
/*      */   protected UserServletContext createContext(HttpServletRequest req, HttpServletResponse resp, UserServlet servlet) throws UserServletException, ServiceException
/*      */   {
/*  287 */     return new UserServletContext(req, resp, servlet);
/*      */   }
/*      */   
/*      */   public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
/*      */   {
/*  292 */     UserServletContext context = null;
/*  293 */     ZimbraLog.clearContext();
/*  294 */     addRemoteIpToLoggingContext(req);
/*      */     try {
/*  296 */       context = createContext(req, resp, this);
/*  297 */       if (!checkAuthentication(context)) {
/*  298 */         sendError(context, req, resp, L10nUtil.getMessage(L10nUtil.MsgKey.errMustAuthenticate, req, new Object[0]));
/*      */       }
/*      */       else
/*      */       {
/*  302 */         checkTargetAccountStatus(context);
/*      */         
/*  304 */         if (proxyIfRemoteTargetAccount(req, resp, context)) {
/*      */           return;
/*      */         }
/*      */         
/*      */ 
/*      */ 
/*  310 */         if (context.getAuthAccount() != null) {
/*  311 */           ZimbraLog.addAccountNameToContext(context.getAuthAccount().getName());
/*      */         }
/*      */         
/*  314 */         doAuthGet(req, resp, context);
/*      */       }
/*      */     } catch (ServiceException se) {
/*  317 */       if ((se.getCode() == "service.PERM_DENIED") || ((se instanceof MailServiceException.NoSuchItemException)))
/*      */       {
/*  319 */         sendError(context, req, resp, L10nUtil.getMessage(L10nUtil.MsgKey.errNoSuchItem, req, new Object[0]));
/*  320 */       } else if ((se.getCode() == "account.MAINTENANCE_MODE") || (se.getCode() == "account.ACCOUNT_INACTIVE"))
/*      */       {
/*  322 */         sendError(context, req, resp, se.getMessage());
/*      */       } else {
/*  324 */         throw new ServletException(se);
/*      */       }
/*      */     } catch (UserServletException e) {
/*  327 */       resp.sendError(e.getHttpStatusCode(), e.getMessage());
/*      */     } finally {
/*  329 */       ZimbraLog.clearContext();
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */   private boolean checkAuthentication(UserServletContext context)
/*      */     throws IOException, ServletException, UserServletException
/*      */   {
/*  337 */     if ((context.targetAccount == null) && (context.accountPath != null) && (context.accountPath.equals("~"))) {
/*  338 */       UserServletUtil.getAccount(context);
/*  339 */       if (context.getAuthAccount() == null) {
/*  340 */         return false;
/*      */       }
/*  342 */       context.targetAccount = context.getAuthAccount();
/*      */     }
/*      */     
/*      */ 
/*  346 */     UserServletUtil.getAccount(context);
/*  347 */     if (context.getAuthAccount() == null) {
/*  348 */       context.setAnonymousRequest();
/*      */     }
/*  350 */     return true;
/*      */   }
/*      */   
/*      */   private void checkTargetAccountStatus(UserServletContext context) throws ServiceException {
/*  354 */     if (context.targetAccount != null) {
/*  355 */       String acctStatus = context.targetAccount.getAccountStatus(Provisioning.getInstance());
/*      */       
/*      */ 
/*  358 */       if ("maintenance".equals(acctStatus)) {
/*  359 */         throw AccountServiceException.MAINTENANCE_MODE();
/*      */       }
/*      */       
/*  362 */       if ((!"active".equals(acctStatus)) && ((context.authToken == null) || ((!context.authToken.isDelegatedAuth()) && (!AdminAccessControl.isAdequateAdminAccount(context.getAuthAccount())))))
/*      */       {
/*      */ 
/*  365 */         throw AccountServiceException.ACCOUNT_INACTIVE(context.targetAccount.getName());
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   protected static AuthToken getProxyAuthToken(UserServletContext context) throws ServiceException {
/*  371 */     String encoded = Provisioning.getInstance().getProxyAuthToken(context.targetAccount.getId(), null);
/*  372 */     if (encoded != null)
/*  373 */       return new ZimbraAuthTokenEncoded(encoded);
/*  374 */     if (context.basicAuthHappened) {
/*  375 */       return context.authToken;
/*      */     }
/*  377 */     return null;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   protected boolean proxyIfRemoteTargetAccount(HttpServletRequest req, HttpServletResponse resp, UserServletContext context)
/*      */     throws IOException, ServiceException
/*      */   {
/*  386 */     if ((context.targetAccount != null) && (!Provisioning.onLocalServer(context.targetAccount))) {
/*  387 */       proxyServletRequest(req, resp, Provisioning.getInstance().getServer(context.targetAccount), getProxyAuthToken(context));
/*  388 */       return true;
/*      */     }
/*      */     
/*  391 */     return false;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static String getExternalRestUrl(OperationContext octxt, Mountpoint mpt)
/*      */     throws ServiceException
/*      */   {
/*  402 */     AuthToken authToken = AuthToken.getCsrfUnsecuredAuthToken(octxt.getAuthToken());
/*      */     
/*      */ 
/*  405 */     if (mpt.isLocal()) {
/*  406 */       return null;
/*      */     }
/*      */     
/*  409 */     String folderPath = null;
/*      */     
/*      */ 
/*      */ 
/*  413 */     Provisioning prov = Provisioning.getInstance();
/*  414 */     Account targetAccount = prov.get(Key.AccountBy.id, mpt.getOwnerId());
/*  415 */     if (targetAccount == null)
/*      */     {
/*  417 */       return null;
/*      */     }
/*  419 */     Server targetServer = prov.getServer(targetAccount);
/*      */     
/*      */ 
/*      */ 
/*  423 */     if (Provisioning.onLocalServer(targetAccount)) {
/*  424 */       Mailbox mailbox = MailboxManager.getInstance().getMailboxByAccountId(targetAccount.getId());
/*  425 */       if (mailbox == null)
/*      */       {
/*  427 */         return null;
/*      */       }
/*      */       
/*  430 */       Folder folder = mailbox.getFolderById(octxt, mpt.getRemoteId());
/*  431 */       if (folder == null) {
/*  432 */         return null;
/*      */       }
/*  434 */       folderPath = folder.getPath();
/*      */     }
/*      */     else
/*      */     {
/*  438 */       ZMailbox.Options zoptions = new ZMailbox.Options(authToken.toZAuthToken(), AccountUtil.getSoapUri(targetAccount));
/*  439 */       zoptions.setTargetAccount(mpt.getOwnerId());
/*  440 */       zoptions.setTargetAccountBy(Key.AccountBy.id);
/*  441 */       zoptions.setNoSession(true);
/*  442 */       ZMailbox zmbx = ZMailbox.getMailbox(zoptions);
/*  443 */       if (zmbx == null)
/*      */       {
/*  445 */         return null;
/*      */       }
/*      */       
/*      */ 
/*  449 */       ZFolder folder = zmbx.getFolderById(mpt.getTarget().toString(authToken.getAccount().getId()));
/*      */       
/*  451 */       if (folder == null) {
/*  452 */         return null;
/*      */       }
/*  454 */       folderPath = folder.getPath();
/*      */     }
/*      */     
/*  457 */     return URLUtil.getServiceURL(targetServer, "/home" + HttpUtil.urlEscape(new StringBuilder().append(getAccountPath(targetAccount)).append(folderPath).toString()), true);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static String getExternalRestUrl(Folder folder)
/*      */     throws ServiceException
/*      */   {
/*  470 */     Provisioning prov = Provisioning.getInstance();
/*  471 */     Account targetAccount = folder.getAccount();
/*      */     
/*  473 */     Server targetServer = prov.getServer(targetAccount);
/*      */     
/*      */ 
/*  476 */     return URLUtil.getServiceURL(targetServer, "/home" + HttpUtil.urlEscape(new StringBuilder().append(getAccountPath(targetAccount)).append(folder.getPath()).toString()), true);
/*      */   }
/*      */   
/*      */   protected void resolveItems(UserServletContext context) throws ServiceException, IOException {
/*  480 */     UserServletUtil.resolveItems(context);
/*      */   }
/*      */   
/*      */   protected MailItem resolveItem(UserServletContext context) throws ServiceException, IOException {
/*  484 */     return UserServletUtil.resolveItem(context, true);
/*      */   }
/*      */   
/*      */   private void doAuthGet(HttpServletRequest req, HttpServletResponse resp, UserServletContext context) throws ServletException, IOException, ServiceException, UserServletException
/*      */   {
/*  489 */     if (log.isDebugEnabled()) {
/*  490 */       StringBuffer reqURL = context.req.getRequestURL();
/*  491 */       String queryParam = context.req.getQueryString();
/*  492 */       if (queryParam != null) reqURL.append('?').append(queryParam);
/*  493 */       log.debug("UserServlet: " + reqURL.toString());
/*      */     }
/*      */     
/*  496 */     context.opContext = new OperationContext(context.getAuthAccount(), isAdminRequest(req));
/*  497 */     Mailbox mbox = UserServletUtil.getTargetMailbox(context);
/*  498 */     if (mbox != null) {
/*  499 */       ZimbraLog.addMboxToContext(mbox.getId());
/*  500 */       if (context.reqListIds != null) {
/*  501 */         resolveItems(context);
/*      */       } else {
/*  503 */         MailItem item = resolveItem(context);
/*  504 */         if (proxyIfMountpoint(req, resp, context, item))
/*      */         {
/*  506 */           return;
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*  511 */     if (FormatterFactory.FormatType.FREE_BUSY.equals(context.format))
/*      */     {
/*      */ 
/*      */ 
/*      */ 
/*  516 */       context.fakeTarget = new UserServletContext.FakeFolder(context.accountPath, "/Calendar", "Calendar");
/*      */     }
/*      */     
/*  519 */     resolveFormatter(context);
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  524 */     if ((mbox == null) && (context.formatter.requiresAuth())) {
/*  525 */       throw ServiceException.PERM_DENIED(L10nUtil.getMessage(L10nUtil.MsgKey.errPermissionDenied, req, new Object[0]));
/*      */     }
/*  527 */     String cacheControlValue = LC.rest_response_cache_control_value.value();
/*  528 */     if (!StringUtil.isNullOrEmpty(cacheControlValue)) {
/*  529 */       resp.addHeader("Cache-Control", cacheControlValue);
/*      */     }
/*      */     
/*  532 */     context.formatter.format(context);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public void doPut(HttpServletRequest req, HttpServletResponse resp)
/*      */     throws ServletException, IOException
/*      */   {
/*  540 */     doPost(req, resp);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public void doPost(HttpServletRequest req, HttpServletResponse resp)
/*      */     throws ServletException, IOException
/*      */   {
/*  548 */     UserServletContext context = null;
/*  549 */     ZimbraLog.clearContext();
/*  550 */     addRemoteIpToLoggingContext(req);
/*      */     try {
/*  552 */       context = new UserServletContext(req, resp, this);
/*  553 */       if (!checkAuthentication(context)) {
/*  554 */         sendError(context, req, resp, L10nUtil.getMessage(L10nUtil.MsgKey.errMustAuthenticate, req, new Object[0]));
/*      */       }
/*      */       else
/*      */       {
/*  558 */         checkTargetAccountStatus(context);
/*  559 */         if (proxyIfRemoteTargetAccount(req, resp, context)) {
/*      */           return;
/*      */         }
/*  562 */         if (context.getAuthAccount() != null) {
/*  563 */           ZimbraLog.addAccountNameToContext(context.getAuthAccount().getName());
/*      */         }
/*      */         
/*  566 */         boolean doCsrfCheck = false;
/*  567 */         if (req.getAttribute("CsrfTokenCheck") != null) {
/*  568 */           doCsrfCheck = ((Boolean)req.getAttribute("CsrfTokenCheck")).booleanValue();
/*      */         }
/*      */         
/*  571 */         if (doCsrfCheck) {
/*  572 */           String csrfToken = req.getHeader("X-Zimbra-Csrf-Token");
/*  573 */           if (log.isDebugEnabled()) {
/*  574 */             String paramValue = req.getParameter("auth");
/*  575 */             log.debug("CSRF check is: %s, CSRF token is: %s, Authentication recd with request is: %s", new Object[] { Boolean.valueOf(doCsrfCheck), csrfToken, paramValue });
/*      */           }
/*      */           
/*      */ 
/*      */ 
/*  580 */           if (!StringUtil.isNullOrEmpty(csrfToken)) {
/*  581 */             if (!CsrfUtil.isValidCsrfToken(csrfToken, context.authToken)) {
/*  582 */               context.setCsrfAuthSucceeded(Boolean.FALSE.booleanValue());
/*  583 */               log.debug("CSRF token validation failed for account: %s, Auth token is CSRF enabled:  %sCSRF token is: %s", new Object[] { context.authToken, Boolean.valueOf(context.authToken.isCsrfTokenEnabled()), csrfToken });
/*      */               
/*      */ 
/*  586 */               sendError(context, req, resp, L10nUtil.getMessage(L10nUtil.MsgKey.errMustAuthenticate, req, new Object[0])); return;
/*      */             }
/*      */             
/*      */ 
/*  590 */             context.setCsrfAuthSucceeded(Boolean.TRUE.booleanValue());
/*      */           }
/*      */         }
/*      */         
/*  594 */         Folder folder = null;
/*  595 */         String filename = null;
/*  596 */         Mailbox mbox = UserServletUtil.getTargetMailbox(context);
/*  597 */         if (mbox != null) {
/*  598 */           ZimbraLog.addMboxToContext(mbox.getId());
/*      */           
/*  600 */           log.info("POST: " + context.req.getRequestURL().toString());
/*      */           
/*  602 */           context.opContext = new OperationContext(context.getAuthAccount(), isAdminRequest(req));
/*      */           try
/*      */           {
/*  605 */             context.target = UserServletUtil.resolveItem(context, false);
/*      */           }
/*      */           catch (MailServiceException.NoSuchItemException nsie) {
/*  608 */             if (context.itemPath == null)
/*  609 */               throw nsie;
/*  610 */             int separator = context.itemPath.lastIndexOf('/');
/*  611 */             if (separator <= 0)
/*  612 */               throw nsie;
/*  613 */             filename = context.itemPath.substring(separator + 1);
/*  614 */             context.itemPath = context.itemPath.substring(0, separator);
/*  615 */             context.target = UserServletUtil.resolveItem(context, false);
/*  616 */             context.extraPath = filename;
/*      */           }
/*      */           
/*  619 */           folder = (context.target instanceof Folder) ? (Folder)context.target : mbox.getFolderById(context.opContext, context.target.getFolderId());
/*      */           
/*  621 */           if (context.target != folder) {
/*  622 */             if (filename == null) {
/*  623 */               filename = context.target.getName();
/*      */             }
/*      */             else {
/*  626 */               throw MailServiceException.NO_SUCH_FOLDER(context.itemPath);
/*      */             }
/*      */           }
/*  629 */           if (proxyIfMountpoint(req, resp, context, folder)) {
/*      */             return;
/*      */           }
/*      */         }
/*      */         
/*      */ 
/*      */ 
/*  636 */         if ((context.format == null) && (filename != null)) {
/*  637 */           context.format = FormatterFactory.FormatType.HTML_CONVERTED;
/*      */         }
/*  639 */         String ctype = context.req.getContentType();
/*      */         
/*      */ 
/*  642 */         if ((context.format == null) && (ctype != null)) {
/*  643 */           String normalizedType = new ContentType(ctype).getContentType();
/*  644 */           Formatter fmt = (Formatter)FormatterFactory.mDefaultFormatters.get(normalizedType);
/*  645 */           if (fmt != null) {
/*  646 */             context.format = fmt.getType();
/*      */           }
/*      */         }
/*  649 */         context.target = folder;
/*  650 */         resolveFormatter(context);
/*  651 */         if (!context.formatter.supportsSave()) {
/*  652 */           sendError(context, req, resp, L10nUtil.getMessage(L10nUtil.MsgKey.errUnsupportedFormat, req, new Object[0]));
/*      */         }
/*      */         
/*      */ 
/*      */ 
/*  657 */         if ((mbox == null) && (context.formatter.requiresAuth())) {
/*  658 */           throw ServiceException.PERM_DENIED(L10nUtil.getMessage(L10nUtil.MsgKey.errPermissionDenied, req, new Object[0]));
/*      */         }
/*  660 */         context.formatter.save(context, ctype, folder, filename);
/*      */       }
/*  662 */     } catch (ServiceException se) { if ((se.getCode() == "service.PERM_DENIED") || ((se instanceof MailServiceException.NoSuchItemException))) {
/*  663 */         sendError(context, req, resp, L10nUtil.getMessage(L10nUtil.MsgKey.errNoSuchItem, req, new Object[0]));
/*  664 */       } else if ((se.getCode() == "account.MAINTENANCE_MODE") || (se.getCode() == "account.ACCOUNT_INACTIVE"))
/*      */       {
/*  666 */         sendError(context, req, resp, se.getMessage());
/*  667 */       } else if (se.getCode() == "service.INVALID_REQUEST") {
/*  668 */         if (log.isDebugEnabled()) {
/*  669 */           log.debug("Invalid POST Request", se);
/*      */         } else {
/*  671 */           log.info("Invalid POST Request - %s", new Object[] { se.getMessage() });
/*      */         }
/*  673 */         resp.sendError(400, se.getMessage());
/*      */       } else {
/*  675 */         if (log.isDebugEnabled()) {
/*  676 */           log.info("Service Exception caught whilst processing POST", se);
/*      */         } else {
/*  678 */           log.info("Service Exception caught whilst processing POST - %s", new Object[] { se.getMessage() });
/*      */         }
/*  680 */         throw new ServletException(se);
/*      */       }
/*      */     }
/*      */     catch (UserServletException e) {
/*  684 */       if (e.getHttpStatusCode() == 401) {
/*  685 */         sendError(context, req, resp, L10nUtil.getMessage(L10nUtil.MsgKey.errMustAuthenticate, req, new Object[0]));
/*      */       }
/*      */       else {
/*  688 */         resp.sendError(e.getHttpStatusCode(), e.getMessage());
/*      */       }
/*      */     } finally {
/*  691 */       ZimbraLog.clearContext();
/*      */     }
/*      */   }
/*      */   
/*      */   private void resolveFormatter(UserServletContext context)
/*      */     throws UserServletException
/*      */   {
/*  698 */     if (context.format == null) {
/*  699 */       context.format = defaultFormat(context);
/*  700 */       if (context.format == null) {
/*  701 */         throw new UserServletException(400, L10nUtil.getMessage(L10nUtil.MsgKey.errUnsupportedFormat, context.req, new Object[0]));
/*      */       }
/*      */     }
/*      */     
/*      */ 
/*  706 */     if (context.formatter == null) {
/*  707 */       context.formatter = ((Formatter)FormatterFactory.mFormatters.get(context.format));
/*  708 */       if (context.formatter == null) {
/*  709 */         throw new UserServletException(400, L10nUtil.getMessage(L10nUtil.MsgKey.errUnsupportedFormat, context.req, new Object[0]));
/*      */       }
/*      */     }
/*      */     
/*  713 */     context.formatter.validateParams(context);
/*      */   }
/*      */   
/*      */   protected boolean proxyIfMountpoint(HttpServletRequest req, HttpServletResponse resp, UserServletContext context, MailItem item) throws IOException, ServiceException, UserServletException
/*      */   {
/*  718 */     if (!(item instanceof Mountpoint))
/*  719 */       return false;
/*  720 */     if ((context.format != null) && (context.format.equals("html")))
/*  721 */       return false;
/*  722 */     Mountpoint mpt = (Mountpoint)item;
/*      */     
/*  724 */     String uri = "/home/~/?id=" + HttpUtil.urlEscape(mpt.getOwnerId()) + "%3A" + mpt.getRemoteId();
/*  725 */     if (context.format != null)
/*  726 */       uri = uri + "&fmt=" + HttpUtil.urlEscape(context.format.toString());
/*  727 */     if (context.extraPath != null)
/*  728 */       uri = uri + "&name=" + HttpUtil.urlEscape(context.extraPath);
/*  729 */     for (Map.Entry<String, String> entry : HttpUtil.getURIParams(req).entrySet()) {
/*  730 */       String qp = (String)entry.getKey();
/*  731 */       if ((!qp.equals("id")) && (!qp.equals("fmt"))) {
/*  732 */         uri = uri + '&' + HttpUtil.urlEscape(qp) + '=' + HttpUtil.urlEscape((String)entry.getValue());
/*      */       }
/*      */     }
/*  735 */     Provisioning prov = Provisioning.getInstance();
/*  736 */     Account targetAccount = prov.get(Key.AccountBy.id, mpt.getOwnerId());
/*  737 */     if (targetAccount == null) {
/*  738 */       throw new UserServletException(400, L10nUtil.getMessage(L10nUtil.MsgKey.errNoSuchAccount, req, new Object[0]));
/*      */     }
/*  740 */     proxyServletRequest(req, resp, prov.getServer(targetAccount), uri, getProxyAuthToken(context));
/*  741 */     return true;
/*      */   }
/*      */   
/*  744 */   private static HashSet<String> ZIMBRA_DOC_CONTENT_TYPE = new HashSet();
/*      */   
/*  746 */   static { ZIMBRA_DOC_CONTENT_TYPE.add("application/x-zimbra-doc");
/*  747 */     ZIMBRA_DOC_CONTENT_TYPE.add("application/x-zimbra-slides");
/*  748 */     ZIMBRA_DOC_CONTENT_TYPE.add("application/x-zimbra-xls");
/*      */   }
/*      */   
/*      */   private FormatterFactory.FormatType defaultFormat(UserServletContext context) {
/*  752 */     if (context.hasPart()) {
/*  753 */       return FormatterFactory.FormatType.HTML_CONVERTED;
/*      */     }
/*  755 */     MailItem.Type type = MailItem.Type.UNKNOWN;
/*  756 */     if ((context.target instanceof Folder)) {
/*  757 */       type = ((Folder)context.target).getDefaultView();
/*  758 */     } else if (context.target != null) {
/*  759 */       type = context.target.getType();
/*      */     }
/*  761 */     switch (type) {
/*      */     case APPOINTMENT: 
/*      */     case TASK: 
/*  764 */       return FormatterFactory.FormatType.ICS;
/*      */     case CONTACT: 
/*  766 */       return (context.target instanceof Folder) ? FormatterFactory.FormatType.CSV : FormatterFactory.FormatType.VCF;
/*      */     
/*      */     case DOCUMENT: 
/*  769 */       if ((context.target instanceof Folder))
/*  770 */         return FormatterFactory.FormatType.HTML;
/*  771 */       String contentType = ((Document)context.target).getContentType();
/*  772 */       if ((contentType != null) && (contentType.indexOf(';') > 0))
/*  773 */         contentType = contentType.substring(0, contentType.indexOf(';')).toLowerCase();
/*  774 */       if (ZIMBRA_DOC_CONTENT_TYPE.contains(contentType))
/*  775 */         return FormatterFactory.FormatType.HTML;
/*  776 */       return FormatterFactory.FormatType.HTML_CONVERTED;
/*      */     }
/*  778 */     return FormatterFactory.FormatType.HTML_CONVERTED;
/*      */   }
/*      */   
/*      */   public void init()
/*      */     throws ServletException
/*      */   {
/*  784 */     log.info("Starting up");
/*  785 */     super.init();
/*      */   }
/*      */   
/*      */   public void destroy()
/*      */   {
/*  790 */     log.info("Shutting down");
/*  791 */     super.destroy();
/*      */   }
/*      */   
/*      */   public static byte[] getRemoteContent(AuthToken authToken, ItemId iid, Map<String, String> params) throws ServiceException {
/*  795 */     Account target = Provisioning.getInstance().get(Key.AccountBy.id, iid.getAccountId(), authToken);
/*  796 */     Map<String, String> pcopy = new HashMap(params);
/*  797 */     pcopy.put("id", iid.toString());
/*  798 */     return getRemoteContent(authToken, target, (String)null, pcopy);
/*      */   }
/*      */   
/*      */   public static byte[] getRemoteContent(AuthToken authToken, Account target, String folder, Map<String, String> params) throws ServiceException {
/*  802 */     return getRemoteContent(authToken.toZAuthToken(), getRemoteUrl(target, folder, params));
/*      */   }
/*      */   
/*      */   public static byte[] getRemoteContent(ZAuthToken authToken, String url) throws ServiceException {
/*  806 */     return (byte[])getRemoteResource(authToken, url).getSecond();
/*      */   }
/*      */   
/*      */   public static HttpInputStream getRemoteContentAsStream(AuthToken authToken, Account target, String folder, Map<String, String> params) throws ServiceException, IOException {
/*  810 */     String url = getRemoteUrl(target, folder, params);
/*  811 */     return (HttpInputStream)getRemoteResourceAsStream(authToken.toZAuthToken(), url).getSecond();
/*      */   }
/*      */   
/*      */   private static String getRemoteUrl(Account target, String folder, Map<String, String> params) throws ServiceException {
/*  815 */     if (folder == null) {
/*  816 */       folder = "";
/*      */     } else {
/*  818 */       if (folder.endsWith("/"))
/*  819 */         folder = folder.substring(0, folder.length() - 1);
/*  820 */       if (folder.startsWith("/")) {
/*  821 */         folder = folder.substring(1);
/*      */       }
/*      */     }
/*  824 */     Server server = Provisioning.getInstance().getServer(target);
/*  825 */     StringBuffer url = new StringBuffer(getProxyUrl(null, server, "/home" + getAccountPath(target)));
/*  826 */     if (folder.length() > 0)
/*  827 */       url.append("/").append(folder);
/*  828 */     url.append("/?").append("auth").append('=').append("co");
/*  829 */     if (params != null) {
/*  830 */       for (Map.Entry<String, String> param : params.entrySet())
/*  831 */         url.append('&').append(HttpUtil.urlEscape((String)param.getKey())).append('=').append(HttpUtil.urlEscape((String)param.getValue()));
/*      */     }
/*  833 */     return url.toString();
/*      */   }
/*      */   
/*      */   public static Pair<Header[], byte[]> getRemoteResource(ZAuthToken authToken, String url) throws ServiceException {
/*  837 */     HttpMethod get = null;
/*      */     try {
/*  839 */       Pair<Header[], HttpMethod> pair = doHttpOp(authToken, new GetMethod(url));
/*  840 */       get = (HttpMethod)pair.getSecond();
/*  841 */       return new Pair(pair.getFirst(), get.getResponseBody());
/*      */     } catch (IOException x) {
/*  843 */       throw ServiceException.FAILURE("Can't read response body " + url, x);
/*      */     } finally {
/*  845 */       if (get != null) {
/*  846 */         get.releaseConnection();
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   public static FileUploadServlet.Upload getRemoteResourceAsUpload(AuthToken at, ItemId iid, Map<String, String> params) throws ServiceException, IOException
/*      */   {
/*  853 */     Map<String, String> pcopy = new HashMap(params);
/*  854 */     pcopy.put("id", iid.toString());
/*      */     
/*      */ 
/*  857 */     Provisioning prov = Provisioning.getInstance();
/*  858 */     Account target = prov.get(Key.AccountBy.id, iid.getAccountId(), at);
/*  859 */     String url = getRemoteUrl(target, null, pcopy);
/*      */     
/*  861 */     Pair<Header[], HttpInputStream> response = getRemoteResourceAsStream(at.toZAuthToken(), url);
/*      */     
/*      */ 
/*  864 */     String ctype = "text/plain";String filename = null;
/*  865 */     for (Header hdr : (Header[])response.getFirst()) {
/*  866 */       String hname = hdr.getName().toLowerCase();
/*  867 */       if (hname.equals("content-type")) {
/*  868 */         ctype = hdr.getValue();
/*  869 */       } else if (hname.equals("content-disposition"))
/*  870 */         filename = new ContentDisposition(hdr.getValue()).getParameter("filename");
/*      */     }
/*  872 */     if ((filename == null) || (filename.equals("")))
/*  873 */       filename = new ContentType(ctype).getParameter("name");
/*  874 */     if ((filename == null) || (filename.equals("")))
/*  875 */       filename = "unknown";
/*  876 */     return FileUploadServlet.saveUpload((InputStream)response.getSecond(), filename, ctype, at.getAccountId());
/*      */   }
/*      */   
/*      */   public static class HttpInputStream extends FilterInputStream
/*      */   {
/*      */     private final HttpMethod method;
/*      */     
/*      */     public HttpInputStream(HttpMethod m) throws IOException
/*      */     {
/*  885 */       super();
/*  886 */       this.method = m;
/*      */     }
/*      */     
/*  889 */     public int getContentLength() { String cl = getHeader("Content-Length");
/*  890 */       if (cl != null)
/*  891 */         return Integer.parseInt(cl);
/*  892 */       return -1;
/*      */     }
/*      */     
/*  895 */     public String getHeader(String headerName) { Header cl = this.method.getResponseHeader(headerName);
/*  896 */       if (cl != null)
/*  897 */         return cl.getValue();
/*  898 */       return null;
/*      */     }
/*      */     
/*  901 */     public int getStatusCode() { return this.method.getStatusCode(); }
/*      */     
/*      */     public void close() {
/*  904 */       this.method.releaseConnection();
/*      */     }
/*      */   }
/*      */   
/*      */   public static Pair<Header[], HttpInputStream> getRemoteResourceAsStream(ZAuthToken authToken, ItemId iid, String extraPath) throws ServiceException, IOException
/*      */   {
/*  910 */     Map<String, String> params = new HashMap();
/*  911 */     params.put("id", iid.toString());
/*  912 */     if (extraPath != null)
/*  913 */       params.put("name", extraPath);
/*  914 */     Account target = Provisioning.getInstance().getAccountById(iid.getAccountId());
/*  915 */     String url = getRemoteUrl(target, null, params);
/*  916 */     return getRemoteResourceAsStream(authToken, url);
/*      */   }
/*      */   
/*      */   public static Pair<Integer, InputStream> getRemoteResourceAsStreamWithLength(ZAuthToken authToken, String url) throws ServiceException, IOException {
/*  920 */     HttpInputStream his = (HttpInputStream)getRemoteResourceAsStream(authToken, url).getSecond();
/*  921 */     return new Pair(Integer.valueOf(his.getContentLength()), his);
/*      */   }
/*      */   
/*      */   public static Pair<Header[], HttpInputStream> getRemoteResourceAsStream(ZAuthToken authToken, String url) throws ServiceException, IOException
/*      */   {
/*  926 */     Pair<Header[], HttpMethod> pair = doHttpOp(authToken, new GetMethod(url));
/*  927 */     return new Pair(pair.getFirst(), new HttpInputStream((HttpMethod)pair.getSecond()));
/*      */   }
/*      */   
/*      */   public static Pair<Header[], HttpInputStream> putMailItem(ZAuthToken authToken, String url, MailItem item) throws ServiceException, IOException
/*      */   {
/*  932 */     if ((item instanceof Document)) {
/*  933 */       Document doc = (Document)item;
/*  934 */       StringBuilder u = new StringBuilder(url);
/*  935 */       u.append("?").append("auth").append('=').append("co");
/*  936 */       if (doc.getType() == MailItem.Type.WIKI) {
/*  937 */         u.append("&fmt=wiki");
/*      */       }
/*  939 */       PutMethod method = new PutMethod(u.toString());
/*  940 */       String contentType = doc.getContentType();
/*  941 */       method.addRequestHeader("Content-Type", contentType);
/*  942 */       method.setRequestEntity(new InputStreamRequestEntity(doc.getContentStream(), doc.getSize(), contentType));
/*  943 */       method = (PutMethod)HttpClientUtil.addInputStreamToHttpMethod(method, doc.getContentStream(), doc.getSize(), contentType);
/*  944 */       method.addRequestHeader("X-Zimbra-Description", doc.getDescription());
/*  945 */       method.setRequestEntity(new InputStreamRequestEntity(doc.getContentStream(), doc.getSize(), contentType));
/*  946 */       Pair<Header[], HttpMethod> pair = doHttpOp(authToken, method);
/*  947 */       return new Pair(pair.getFirst(), new HttpInputStream((HttpMethod)pair.getSecond()));
/*      */     }
/*  949 */     return putRemoteResource(authToken, url, item.getContentStream(), null);
/*      */   }
/*      */   
/*      */   public static Pair<Header[], HttpInputStream> putRemoteResource(AuthToken authToken, String url, InputStream req, Header[] headers)
/*      */     throws ServiceException, IOException
/*      */   {
/*  955 */     return putRemoteResource(authToken.toZAuthToken(), url, req, headers);
/*      */   }
/*      */   
/*      */   public static Pair<Header[], HttpInputStream> putRemoteResource(ZAuthToken authToken, String url, InputStream req, Header[] headers) throws ServiceException, IOException
/*      */   {
/*  960 */     StringBuilder u = new StringBuilder(url);
/*  961 */     u.append("?").append("auth").append('=').append("co");
/*  962 */     PutMethod method = new PutMethod(u.toString());
/*  963 */     String contentType = "application/octet-stream";
/*  964 */     if (headers != null) {
/*  965 */       for (Header hdr : headers) {
/*  966 */         String name = hdr.getName();
/*  967 */         method.addRequestHeader(hdr);
/*  968 */         if (name.equals("Content-Type"))
/*  969 */           contentType = hdr.getValue();
/*      */       }
/*      */     }
/*  972 */     method.setRequestEntity(new InputStreamRequestEntity(req, contentType));
/*  973 */     Pair<Header[], HttpMethod> pair = doHttpOp(authToken, method);
/*  974 */     return new Pair(pair.getFirst(), new HttpInputStream((HttpMethod)pair.getSecond()));
/*      */   }
/*      */   
/*      */   private static Pair<Header[], HttpMethod> doHttpOp(ZAuthToken authToken, HttpMethod method)
/*      */     throws ServiceException
/*      */   {
/*  980 */     String url = "";
/*  981 */     String hostname = "";
/*      */     try {
/*  983 */       url = method.getURI().toString();
/*  984 */       hostname = method.getURI().getHost();
/*      */     } catch (IOException e) {
/*  986 */       log.warn("can't parse target URI", e);
/*      */     }
/*      */     
/*  989 */     HttpClient client = ZimbraHttpConnectionManager.getInternalHttpConnMgr().newHttpClient();
/*  990 */     Map<String, String> cookieMap = authToken.cookieMap(false);
/*  991 */     if (cookieMap != null) {
/*  992 */       HttpState state = new HttpState();
/*  993 */       for (Map.Entry<String, String> ck : cookieMap.entrySet()) {
/*  994 */         state.addCookie(new Cookie(hostname, (String)ck.getKey(), (String)ck.getValue(), "/", null, false));
/*      */       }
/*  996 */       client.setState(state);
/*  997 */       client.getParams().setCookiePolicy("compatibility");
/*      */     }
/*      */     
/* 1000 */     if ((method instanceof PutMethod)) {
/* 1001 */       long contentLength = ((PutMethod)method).getRequestEntity().getContentLength();
/* 1002 */       if (contentLength > 0L) {
/* 1003 */         int timeEstimate = Math.max(10000, (int)(contentLength / 100L));
/*      */         
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/* 1010 */         method.getParams().setSoTimeout(timeEstimate);
/*      */       }
/*      */     }
/*      */     try
/*      */     {
/* 1015 */       int statusCode = HttpClientUtil.executeMethod(client, method);
/* 1016 */       if ((statusCode == 404) || (statusCode == 403))
/* 1017 */         throw MailServiceException.NO_SUCH_ITEM(-1);
/* 1018 */       if ((statusCode != 200) && (statusCode != 201) && (statusCode != 204))
/*      */       {
/*      */ 
/* 1021 */         throw ServiceException.RESOURCE_UNREACHABLE(method.getStatusText(), null, new ServiceException.Argument[] { new ServiceException.InternalArgument("http_url", url, ServiceException.Argument.Type.STR), new ServiceException.InternalArgument("http_code", statusCode, ServiceException.Argument.Type.NUM) });
/*      */       }
/*      */       
/*      */ 
/* 1025 */       List<Header> headers = new ArrayList(Arrays.asList(method.getResponseHeaders()));
/* 1026 */       headers.add(new Header("X-Zimbra-Http-Status", "" + statusCode));
/* 1027 */       return new Pair(headers.toArray(new Header[0]), method);
/*      */     } catch (HttpException e) {
/* 1029 */       throw ServiceException.RESOURCE_UNREACHABLE("HttpException while fetching " + url, e, new ServiceException.Argument[0]);
/*      */     } catch (IOException e) {
/* 1031 */       throw ServiceException.RESOURCE_UNREACHABLE("IOException while fetching " + url, e, new ServiceException.Argument[0]);
/*      */     }
/*      */   }
/*      */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/UserServlet.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */